//
//  HNActionFlowCenter.m
//  HeroNuts
//
//  Created by Magic on 4/2/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "HNActionFlowCenter.h"
#import "HNAction.h"
#import "GameScene.h"
#import "HNFly.h"
#import "HNWalk.h"
#import "HNTurnAround.h"
#import "HNAttack.h"
#import "HNBeaten.h"
#import "HNDie.h"
#import "HNLogicCenter.h"
#import "HNEffect.h"

@interface HNActionFlowCenter ()

- (void)stageMovePreparation;
- (void)stageTurnToEnemyPreparation;
- (void)stageAttackPreparation;
- (void)stageRestoreFacingPreparation;
- (void)onStageBegin;
- (void)onStageEnd;
- (void)onActionFinished;
- (void)runCurrentAction;

@end



@implementation HNActionFlowCenter

@synthesize targetActor = targetActor_;
@synthesize targetPosition = targetPosition_;

static HNActionFlowCenter* sharedActionFlowCenter_ = nil;

#pragma mark HNActionFlowCenter - singleton

+ (HNActionFlowCenter*) sharedActionFlowCenter
{
	if (!sharedActionFlowCenter_)
		sharedActionFlowCenter_ = [[HNActionFlowCenter alloc] init];
	
	return sharedActionFlowCenter_;
}

#pragma mark HNActionFlowCenter - alloc, init, dealloc

+(id)alloc
{
	NSAssert(sharedActionFlowCenter_ == nil, @"Attempted to allocate a second instance of a singleton.");
	return [super alloc];
}

-(id) init
{
	if( (self=[super init]) ) {
		actions_ = [[NSMutableArray alloc] initWithCapacity:10];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onActionFinished) name:@"ACTIONFINISHED" object:nil];
	}
	
	return self;
}

-(void) dealloc
{
    [targetPosition_ release];
    [targetActor_ release];
	[actions_ release];
	[super dealloc];
}

#pragma mark HNActionFlowCenter - interface for touch processor

- (void)currentActorMoveTo:(HNLogicPosition *)position attack:(HNActor *)target
{
    self.targetActor = target;
    self.targetPosition = position;
    
    currentStage_ = 0;
    
    stageCount_ = 0;

    if (position) {
        //move
        stages_[stageCount_++] = kStageMove;        
        
    }
    if (target) {
        //attack
        stages_[stageCount_++] = kStageTurnToEnemy;
        stages_[stageCount_++] = kStageAttack;
    }
    
    stages_[stageCount_++] = kStageRestoreFacing;
    
    [self onStageBegin];
}

- (void)currentActorShootAt:(HNActor*)target
{
    
}

#pragma mark HNActionFlowCenter - stage stuffs

- (void)onStageBegin
{
    switch (stages_[currentStage_]) {
        case kStageMove:
            [self stageMovePreparation];
            break;
            
        case kStageTurnToEnemy:
            [self stageTurnToEnemyPreparation];
            break;
            
        case kStageAttack:
            [self stageAttackPreparation];
            break;
            
        case kStageRestoreFacing:
            [self stageRestoreFacingPreparation];
            break;
            
    }
    
    if ([actions_ count] > 0) {
        currentAction_ = 0;
        [self runCurrentAction];
    }
    else {
        [self onStageEnd];
    }
}

- (void)onStageEnd
{
	if ([actions_ count] > 0) {
		[actions_ removeAllObjects];
	}
	
    currentStage_++;
    
    if (currentStage_ < stageCount_) {
        //move on to next stage
        
		[self onStageBegin];
    }
    else {
        //move on to next actor
        [[GameScene sharedGameScene] nextActor];

    }
}

- (void)stageMovePreparation
{
    NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
    
    HNActor *currentActor = [GameScene sharedGameScene].currentActor;
    
    NSLog(@"current actor original x : %f",currentActor.sprite.position.x);
    
    [action setValue:currentActor forKey:@"target"];
    
    if ([currentActor canFly]) {
        [[HNGroundLogic sharedGroundLogic] getWalkRoute:[targetPosition_ position]];//!!!!!
        HNFly *fly = [[HNFly alloc] initWithActorName:currentActor.name 
                                             from:currentActor.position 
                                               to:[targetPosition_ position] 
                                        faceRight:currentActor.faceRight];
        [action setValue:fly forKey:@"action"];
        [fly release];
    }
    else {

        NSMutableArray *path = [[HNGroundLogic sharedGroundLogic] getWalkRoute:[targetPosition_ position]];
        HNWalk *walk = [[HNWalk alloc] initWithActorName:currentActor.name 
                                            walkPath:path 
                                           faceRight:currentActor.faceRight];
        [action setValue:walk forKey:@"action"];
        [walk release];
    }
    
    [actions_ addObject:action];
    
    [action release];
}

- (void)stageTurnToEnemyPreparation
{
    HNActor *currentActor = [GameScene sharedGameScene].currentActor;
    HNActor *leftActor;
    HNActor *rightActor;
    
    CGPoint distanceFromCurrentTotarget = [HNLogicPosition distanceInPixelsFrom:currentActor.position 
                                                                             to:targetActor_.position];
    if (distanceFromCurrentTotarget.x > 0) {
        leftActor = currentActor;
        rightActor = targetActor_;
    }
    else {
        leftActor = targetActor_;
        rightActor = currentActor;
    }
    
    if (!leftActor.faceRight) {
        HNTurnAround *turnAround = [[HNTurnAround alloc] initWithActorName:leftActor.name];
        
        NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
        [action setValue:leftActor forKey:@"target"];
        [action setValue:turnAround forKey:@"action"];
        [actions_ addObject:action];
        
        [action release];
        [turnAround release];
    }
    
    if (rightActor.faceRight) {
        HNTurnAround *turnAround = [[HNTurnAround alloc] initWithActorName:rightActor.name];
        
        NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
        [action setValue:rightActor forKey:@"target"];
        [action setValue:turnAround forKey:@"action"];
        [actions_ addObject:action];
        
        [action release];   
        [turnAround release];
    }
}

- (void)stageAttackPreparation
{
    HNActor *currentActor = [GameScene sharedGameScene].currentActor; 
    
    NSString *direction;
    float yDistance = currentActor.position.y - targetActor_.position.y;
    
    if (yDistance > 0) {
        direction = [NSString stringWithString:@"DOWN"];
    }
    else{
        if (yDistance == 0) {
            direction = [NSString stringWithString:@"FRONT"];
        }
        else{
            direction = [NSString stringWithString:@"UP"];
        }
    }
    
    HNLogicCenter *logicCenter = [[NSClassFromString(@"LogicCenter") alloc] init];
    [logicCenter actorA:currentActor attackActorB:targetActor_];
    
    NSMutableArray* nsa = [logicCenter getActionQueue];
    for (NSDictionary *dic in nsa) {
        for (NSString *actionName in dic) {
            NSLog(@"action :%@",actionName);
            HNActor *target = [dic valueForKey:actionName];
            
            NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
            
            if ([actionName isEqualToString:@"attack"]) {
                HNAttack *attack = [[HNAttack alloc] initWithActorName:target.name direction:direction];
                
                [action setValue:target forKey:@"target"];
                [action setValue:attack forKey:@"action"];
                
                [attack release];
            }
            else if ([actionName isEqualToString:@"beattacked"]) {
                HNBeaten *beaten = [[HNBeaten alloc] initWithActorName:target.name];
            
                [action setValue:target forKey:@"target"];
                [action setValue:beaten forKey:@"action"];

                [beaten release];
            }
            else if ([actionName isEqualToString:@"die"]) {
                HNDie *die = [[HNDie alloc] initWithActorName:target.name];
                
                [action setValue:target forKey:@"target"];
                [action setValue:die forKey:@"action"];
                
                [die release];
            }
            else if ([[actionName substringWithRange:NSMakeRange(0, 2)] isEqualToString:@"e_"]) {
                HNEffect *effect = [[HNEffect alloc] initWithEffectName:[actionName substringFromIndex:2]];
                
                [action setValue:target forKey:@"target"];
                [action setValue:effect forKey:@"action"];
                
                [effect release];
            }
            
            [actions_ addObject:action];
            [action release];
        }
    }
    
    [logicCenter release];
}

- (void)stageRestoreFacingPreparation
{
    HNActor *currentActor = [GameScene sharedGameScene].currentActor;
    
    if (currentActor.leftSide != currentActor.faceRight) 
	{
        HNTurnAround *turnAround = [[HNTurnAround alloc] initWithActorName:currentActor.name]; 
        
        NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
        [action setValue:currentActor forKey:@"target"];
        [action setValue:turnAround forKey:@"action"];
        [actions_ addObject:action];
        
        [action release];
        [turnAround release];
    }
    

	if (targetActor_)
    if (targetActor_.leftSide != targetActor_.faceRight)
	{
        HNTurnAround *turnAround = [[HNTurnAround alloc] initWithActorName:targetActor_.name];
        
        NSMutableDictionary *action = [[NSMutableDictionary alloc] init];
        [action setValue:targetActor_ forKey:@"target"];
        [action setValue:turnAround forKey:@"action"];
        [actions_ addObject:action];
        
        [turnAround release];
        [action release];
    }
}

#pragma mark HNActionFlowCenter - action stuffs in a stage

- (void)onActionFinished
{
    currentAction_++;
    if (currentAction_ < [actions_ count]) {
        [self runCurrentAction];
    }
    else{
        [self onStageEnd];
    }
}

- (void)runCurrentAction
{
    NSMutableDictionary *currentAction = [actions_ objectAtIndex:currentAction_];
    HNAction *action = [currentAction valueForKey:@"action"];
    HNActor *target = [currentAction valueForKey:@"target"];
    
    [action startWithTarget:target];
}



@end
